Add 'modifier' argument to [IO] field in xcsv. Initially define 'absolute" and ...
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 11 Jan 2006 07:08:33 +0000 (07:08 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 11 Jan 2006 07:08:33 +0000 (07:08 +0000)
gpsbabel/csv_util.c
gpsbabel/csv_util.h
gpsbabel/style/README.style
gpsbabel/xcsv.c

index e7299f667f19c4d8656ee28399e2770353c81456..ba3b55a832a1adb3f7aa8cbaa2c33240128bcddb 100644 (file)
@@ -581,13 +581,14 @@ xcsv_ifield_add(char *key, char *val, char *pfc)
 /* usage: xcsv_ofield_add("LAT_DECIMAL", "", "%08.5lf")                      */
 /*****************************************************************************/
 void
-xcsv_ofield_add(char *key, char *val, char *pfc)
+xcsv_ofield_add(char *key, char *val, char *pfc, int options)
 {
     field_map_t *fmp = xcalloc(sizeof(*fmp), 1);
     
     fmp->key = key;
     fmp->val = val;
     fmp->printfc = pfc;
+    fmp->options = options;
     
     ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q);
     xcsv_file.ofield_ct++;
@@ -1103,10 +1104,17 @@ xcsv_waypt_pr(const waypoint *wpt)
     QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) {
        char *obuff;
         fmp = (field_map_t *) elem;
+       double lat = wpt->latitude;
+       double lon = wpt->longitude;
 
-        if (i != 0) 
+        if ((i != 0) && !(fmp->options & OPTIONS_NODELIM))  
             fprintf (xcsv_file.xcsvfp, write_delimiter);
 
+       if (fmp->options & OPTIONS_ABSOLUTE) {
+               lat = fabs(lat);
+               lon = fabs(lon);
+       }
+
         i++;
 #define writebuff(b, fmt, data) snprintf(b, sizeof(b), fmt, data)
         if (strcmp(fmp->key, "IGNORE") == 0) {
@@ -1180,76 +1188,76 @@ xcsv_waypt_pr(const waypoint *wpt)
         /* LATITUDE CONVERSION***********************************************/
         if (strcmp(fmp->key, "LAT_DECIMAL") == 0) {
             /* latitude as a pure decimal value */
-            writebuff(buff, fmp->printfc, wpt->latitude);
+            writebuff(buff, fmp->printfc, lat);
         } else
         if (strcmp(fmp->key, "LAT_DECIMALDIR") == 0) {
             /* latitude as a decimal value with N/S after it */
-            snprintf(buff, sizeof(buff), fmp->printfc, fabs(wpt->latitude), 
-              LAT_DIR(wpt->latitude));
+            snprintf(buff, sizeof(buff), fmp->printfc, fabs(lat), 
+              LAT_DIR(lat));
         } else
         if (strcmp(fmp->key, "LAT_DIRDECIMAL") == 0) {
             /* latitude as a decimal value with N/S before it */
             snprintf(buff, sizeof(buff), fmp->printfc, 
-              LAT_DIR(wpt->latitude),
-              fabs(wpt->latitude));
+              LAT_DIR(lat),
+              fabs(lat));
         } else
         if (strcmp(fmp->key, "LAT_INT32DEG") == 0) {
             /* latitude as an integer offset from 0 degrees */
             writebuff(buff, fmp->printfc,
-              dec_to_intdeg(wpt->latitude, 1));
+              dec_to_intdeg(lat, 1));
         } else
        if (strcmp(fmp->key, "LAT_HUMAN_READABLE") == 0) {
-           dec_to_human( buff, fmp->printfc, "SN", wpt->latitude );
+           dec_to_human( buff, fmp->printfc, "SN", lat );
        } else
        if (strcmp(fmp->key, "LAT_NMEA") == 0) {
-               writebuff(buff, fmp->printfc, degrees2ddmm(wpt->latitude));
+               writebuff(buff, fmp->printfc, degrees2ddmm(lat));
        } else
 
         /* LONGITUDE CONVERSIONS*********************************************/
         if (strcmp(fmp->key, "LON_DECIMAL") == 0) {
             /* longitude as a pure decimal value */
-            writebuff(buff, fmp->printfc, wpt->longitude);
+            writebuff(buff, fmp->printfc, lon);
         } else
         if (strcmp(fmp->key, "LON_DECIMALDIR") == 0) {
             /* latitude as a decimal value with N/S after it */
             snprintf(buff, sizeof(buff),  fmp->printfc,
-              fabs(wpt->longitude), 
-              LON_DIR(wpt->longitude));
+              fabs(lon), 
+              LON_DIR(lon));
         } else
         if (strcmp(fmp->key, "LON_DIRDECIMAL") == 0) {
             /* latitude as a decimal value with N/S before it */
             snprintf(buff, sizeof(buff), fmp->printfc,
-              LON_DIR(wpt->longitude),
-              fabs(wpt->longitude));
+              LON_DIR(lon),
+              fabs(lon));
         } else
         if (strcmp(fmp->key, "LON_INT32DEG") == 0) {
             /* longitudee as an integer offset from 0 degrees */
             writebuff(buff, fmp->printfc,
-              dec_to_intdeg(wpt->longitude, 0));
+              dec_to_intdeg(lon, 0));
         } else
        if (strcmp(fmp->key, "LON_HUMAN_READABLE") == 0) {
-           dec_to_human( buff, fmp->printfc, "WE", wpt->longitude );
+           dec_to_human( buff, fmp->printfc, "WE", lon );
        } else
        if (strcmp(fmp->key, "LATLON_HUMAN_READABLE") == 0) {
-           dec_to_human( buff, fmp->printfc, "SN", wpt->latitude );
+           dec_to_human( buff, fmp->printfc, "SN", lat );
            if ( !isspace(buff[strlen(buff)])) strcat( buff, " " );
            dec_to_human( buff+strlen(buff), fmp->printfc, "WE", 
-                           wpt->longitude );
+                           lon );
        } else
        if (strcmp(fmp->key, "LON_NMEA") == 0) {
-               writebuff(buff, fmp->printfc, degrees2ddmm(wpt->longitude));
+               writebuff(buff, fmp->printfc, degrees2ddmm(lon));
        } else
 
         /* DIRECTIONS *******************************************************/
         if (strcmp(fmp->key, "LAT_DIR") == 0) {
             /* latitude N/S as a char */
             writebuff(buff, fmp->printfc,
-            LAT_DIR(wpt->latitude));
+            LAT_DIR(lat));
         } else
         if (strcmp(fmp->key, "LON_DIR") == 0) {
             /* longitude E/W as a char */
             writebuff(buff, fmp->printfc,
-              LON_DIR(wpt->longitude));
+              LON_DIR(lon));
         } else
 
         /* ALTITUDE CONVERSIONS**********************************************/
index a69803e740a9713f0f9ae170d4f28d136d97d49d..ef00a5963b83cc4f315be9796a76b272f234f74b 100644 (file)
@@ -60,7 +60,7 @@ void
 xcsv_ifield_add(char *, char *, char *);
 
 void 
-xcsv_ofield_add(char *, char *, char *);
+xcsv_ofield_add(char *, char *, char *, int options);
 
 void 
 xcsv_destroy_style(void);
@@ -73,11 +73,14 @@ xcsv_get_char_from_constant_table(char *key);
 /****************************************************************************/
 
 /* something to map fields to waypts */
+#define OPTIONS_NODELIM 1
+#define OPTIONS_ABSOLUTE 2
 typedef struct field_map {
        queue Q;
        char * key;
        char * val;
        char * printfc;
+       int options;
 } field_map_t;
 
 /* a queuing struct for prologues / epilogues */
index 5ae8687eb50db178d442e47fb89fc2e3bf0a857a..cbe384f19efcb5d7299f79a1c2deedb9c65251e9 100644 (file)
@@ -164,12 +164,21 @@ IFIELDS are use as both input and output.  The existence of OFIELDS is
 primarily to allow more flexible mapping of GPSBabel data to output data 
 (say, for instance, to map the internal GPSBabel "description" variable to 
 two or more fields on output).  For all practical purposes, IFIELDS and 
-OFIELDS are defined the same way in the style file.
+OFIELDS are defined the same way in the style file.  The following options
+are defined:
+
+   o  "no_delim_before" is supported on OFIELD tags to specify that this
+       field should be written without a field delimiter before it.  It's
+       useful for limited field concatenation.
+   o  "absolute" is supported on OFIELD tags for lat and lon to indicate
+       that only absolute values (never negative) are to be printed.
+
 
 There are several different types of fields that may be defined.  Each field 
 consists of three pieces of information: the FIELD TYPE, a DEFAULT VALUE, and 
 a PRINTF CONVERSION (for output).  In many cases, not all pieces are used,
-but all 3 pieces are required.
+but all 3 pieces are required.   Additionally, an fourth field is supported
+that modifies the behaviour of the field being described.
 
 FIELDS should be defined in the style file in the logical order that they
 appear in the data, from left to right.  This is the order in which they are
index bbcffd75ebc990b0e8b061331b506cf76677a3ed..e74b184a77a8e346ac4f3f59042898e3f2881ea4 100644 (file)
@@ -330,6 +330,7 @@ xcsv_parse_style_line(const char *sbuff)
        } else
        
        if (ISSTOKEN(sbuff, "IFIELD")) {
+           int nodelim = 0;
            key = val = pfc = NULL;
            
            s = csv_lineparse(&sbuff[6], ",", "", linecount);
@@ -367,6 +368,7 @@ xcsv_parse_style_line(const char *sbuff)
         * change the world on ifield vs ofield format later..
         */
        if (ISSTOKEN(sbuff, "OFIELD")) {
+           int options = 0;
            key = val = pfc = NULL;
 
            s = csv_lineparse(&sbuff[6], ",", "", linecount);
@@ -386,6 +388,14 @@ xcsv_parse_style_line(const char *sbuff)
                    /* printf conversion */
                    pfc = csv_stringtrim(s, "\"", 1);
                    break;
+               case 3:
+                    /* Any additional options. */
+                    if (strstr(s, "no_delim_before")) {
+                       options |= OPTIONS_NODELIM;
+                    }
+                    if (strstr(s, "absolute")) {
+                       options |= OPTIONS_ABSOLUTE;
+                    }
                default:
                    break;
                }
@@ -393,7 +403,7 @@ xcsv_parse_style_line(const char *sbuff)
                s = csv_lineparse(NULL, ",", "", linecount);
            }
 
-           xcsv_ofield_add(key, val, pfc);
+           xcsv_ofield_add(key, val, pfc, options);
        }
     }
 }